from __future__ import annotations

from dataclasses import dataclass
from typing import List, Dict

from pydantic import BaseModel, Field

from gssgca.transmission_line.multi_weather_sag import sag_under_multiple_weathers
from gssgca.transmission_line.cableway_selection import select_cableway, CablewayScheme
from gssgca.lifting.winch_selection import select_winch, WinchSpec
from gssgca.lifting.block_detailed import reeving_analysis, ReevingResult
from gssgca.crossing.system_analysis import analyze_crossing_system, CrossingSystemForces
from gssgca.foundation.slope_bishop import bishop_simplified, BishopSlice


class WeatherCase(BaseModel):
    name: str
    wind_kPa: float | None = 0
    temp_C: float | None = None
    ice_mm: float | None = 0


class SagRequest(BaseModel):
    span_m: float
    unit_weight_kN_m: float
    elastic_modulus_MPa: float
    area_mm2: float
    alpha_per_C: float
    temp_ref_C: float
    initial_tension_kN: float
    conductor_diameter_mm: float
    weathers: List[WeatherCase]


class SagPoint(BaseModel):
    weather: str
    sag_m: float
    tension_kN: float


def compute_sag_service(req: SagRequest) -> List[SagPoint]:
    pts = sag_under_multiple_weathers(
        span_m=req.span_m,
        unit_weight_kN_m=req.unit_weight_kN_m,
        elastic_modulus_MPa=req.elastic_modulus_MPa,
        area_mm2=req.area_mm2,
        alpha_per_C=req.alpha_per_C,
        temp_ref_C=req.temp_ref_C,
        initial_tension_kN=req.initial_tension_kN,
        conductor_diameter_mm=req.conductor_diameter_mm,
        weather_cases=[w.dict() for w in req.weathers],
    )
    return [SagPoint(weather=p.weather, sag_m=p.sag_m, tension_kN=p.tension_kN) for p in pts]


# --- Cableway selection ---
class CablewayRequest(BaseModel):
    span_m: float
    payload_kN: float
    terrain_category: str = "mountain"
    min_safety_factor: float = 2.5


def cableway_service(req: CablewayRequest) -> CablewayScheme:
    return select_cableway(
        span_m=req.span_m,
        payload_kN=req.payload_kN,
        terrain_category=req.terrain_category, 
        min_safety_factor=req.min_safety_factor,
    )


# --- Winch selection ---
class WinchRequest(BaseModel):
    max_tension_kN: float
    block_efficiency: float = 0.9
    safety_factor: float = 1.25


def winch_service(req: WinchRequest) -> WinchSpec:
    return select_winch(req.max_tension_kN, req.block_efficiency, req.safety_factor)


# --- Block reeving ---
class ReevingRequest(BaseModel):
    hook_load_kN: float
    parts_of_line: int
    sheave_loss_per_pass: float = 0.02
    bearing_loss_per_pass: float = 0.01
    dead_end_eff_factor: float = 0.98


def reeving_service(req: ReevingRequest) -> ReevingResult:
    return reeving_analysis(
        hook_load_kN=req.hook_load_kN,
        parts_of_line=req.parts_of_line,
        sheave_loss_per_pass=req.sheave_loss_per_pass,
        bearing_loss_per_pass=req.bearing_loss_per_pass,
        dead_end_eff_factor=req.dead_end_eff_factor,
    )


# --- Crossing system ---
class CrossingRequest(BaseModel):
    total_vertical_kN: float
    total_horizontal_kN: float
    beam_span_m: float
    num_columns: int = 2
    num_guys: int = 4


def crossing_system_service(req: CrossingRequest) -> CrossingSystemForces:
    return analyze_crossing_system(
        total_vertical_kN=req.total_vertical_kN,
        total_horizontal_kN=req.total_horizontal_kN,
        beam_span_m=req.beam_span_m,
        num_columns=req.num_columns,
        num_guys=req.num_guys,
    )


# --- Bishop slope ---
class BishopRequestSlice(BaseModel):
    width_m: float
    height_m: float
    unit_weight_kN_m3: float
    cohesion_kPa: float
    friction_deg: float
    base_inclination_deg: float
    pore_pressure_kPa: float = 0.0


class BishopRequest(BaseModel):
    slices: List[BishopRequestSlice]


def bishop_service(req: BishopRequest):
    res = bishop_simplified([BishopSlice(**s.dict()) for s in req.slices])
    return res


